from pyparsing import *
from wikitools import wiki, api
import sys
import pdb
from citeparser import CiteParser

import urllib
from urllib2 import *
import string as str
import json
from getch import getch
from userprompt import prompt

MWSection = Forward()
MWSection << (
    Literal('=') + Word(alphas).setResultsName('SectionName') + Literal('=') |
    Literal('=') + MWSection + Literal('=') )

def citeJournal( data ):
    ref = u'{{cite journal'
    ref += u'|author=' + data['Authors'] 
    ref += u'|title=' + data['Title']
    ref += u'|date=' + data['Year']
    ref += u'|volume=' + data['Volume']
    ref += u'|issue=' + data['Issue']
    ref += u'|pages=' + data['FirstPage'] + u' &ndash; ' + data['LastPage']
    ref += u'|doi=' + data['doi']
    ref += u'}}'
    return(ref)

class CitationFixer:
    def __init__(self, use_parser=False ):
        self.__refSections = set()
        self.__wiki = wiki.Wiki("http://www.scholarpedia.org/w/api.php")
        self.__use_parser = use_parser
        self.addReferenceSection('References')

    def addReferenceSection(self, name):
        self.__refSections.add( name )

    def fix( self, title ):
        failedfile = open('parsingfailed.txt','a+')
        cparser = CiteParser()
    
        params = {'action':'query','titles':title,'prop':'revisions','rvprop':'content'}
        req = api.APIRequest(self.__wiki, params)
        crossref = "http://crossref.org/sigg/sigg/FindWorks?version=1&access=API_KEY&format=json&op=OR&expression="
    
        currSection = None
        pages = req.query(querycontinue=False)['query']['pages']
        for pg in [key for key in pages.keys() if key != u'-1']:
            newcontent = ''
            for line in pages[pg][u'revisions'][0][u'*'].splitlines():
                line = str.lstrip(line)
                if len(line)==0:
                    continue
                elif line[0]==u'=':
                    try:
                        res = MWSection.parseString(line)
                        currSection = res['SectionName']
                    except ParseException:
                        currSection = line # unable to parse, so just include all
                    continue
                elif line.startswith('<!--'):
                    continue
                if line[0]==u'*':
                    line = line[1:]
                    newcontent += '*'

                json_data = None
                options = {'s':'(S)kip, keeping original line','x':'E(x)it now'}
                newline = {'s':line}
                pmsg = '--------------\nOriginal line:\n  %s\n'%(newline['s'])

                if self.__use_parser:
                	parsed = cparser.parse(line)
                else:
                    parsed = None

                if not parsed is None:
                    req = crossref + urllib.quote_plus( str.join(parsed))
                    resp = urlopen(req).read()
                    json_data = json.loads(resp)
                    parsed['doi'] = json_data[0][u'doi']

                    if json_data[0][u'normalizedScore'] < 100:
                        pdb.set_trace()
   
                    newline['t'] = citeJournal(parsed)
                    crossref_parsed = replaceWithCrossrefResults(parsed, json_data[0])
                    newline['c'] = citeJournal( crossref_parsed )
                    newline['s'] = line

                    options['c'] = 'Use (c)rossref version: ' + newline['c']
                    options['t'] = 'Use the following (t)emplate version: ' + newline['t']

                elif currSection in self.__refSections: # attempt doi retrieval even though parsed failed
                    if self.__use_parser:
                        pmsg += '\nFailed to parse.\n'

                    options['f'] = 'Append reference to the parsingfailed.txt file and skip.'

                    try:
                        req = crossref + urllib.quote_plus(line)
                        resp = urlopen(req).read()
                        json_data = json.loads(resp)

                        if json_data[0][u'normalizedScore'] == 100:
                            newline['a'] = line + ' doi:' + json_data[0][u'doi']
                            options['a'] = 'Add doi with title: ' + json_data[0][u'title']
                    except KeyError:
                        pass

                pmsg += "\nPlease choose one of the following:"
                if len(options)>2:
                    resp = prompt(pmsg,options)
                else:
                    resp = 's'

                if resp in newline.keys():
                    newcontent += newline[resp] + u'\n'
                elif resp == 'x':
                    failedfile.close()
                    return(None)
                elif resp == 'f':
                    newcontent += newline['s'] + u'\n'
                    failedfile.write(newline['s'] + u'\n')
                else:
                    assert False, "Unexpected key response: "+resp
            print(newcontent)

        failedfile.close()
        return(None)

